---
id: number-input
title: Number Input
description: A field that allows user input of numeric values.
---

<ComponentPreview id="NumberInput" />

## Anatomy

To set up the number input correctly, you'll need to understand its anatomy and how we name its parts.

> Each part includes a `data-part` attribute to help identify them in the DOM.

<Anatomy id="number-input" />

## Examples

Learn how to use the `NumberInput` component in your project. Let's take a look at the most basic example:

<Example id="basic" />

### Setting a minimum and maximum value

Pass the `min` prop or `max` prop to set an upper and lower limit for the input. By default, the input will restrict the
value to stay within the specified range.

<Example id="min-max" />
### Adjusting the precision of the value

In some cases, you might need the value to be rounded to specific decimal points. Set the `formatOptions` and provide
`Intl.NumberFormatOptions` such as `maximumFractionDigits` or `minimumFractionDigits`.

<Example id="fraction-digits" />

### Scrubbing the input value

The NumberInput supports the scrubber interaction pattern. To use this pattern, render the `NumberInput.Scrubber`
component. It uses the Pointer lock API and tracks the pointer movement. It also renders a virtual cursor which mimics
the real cursor's pointer.

<Example id="scrubber" />

### Using the mouse wheel to change value

The NumberInput exposes a way to increment/decrement the value using the mouse wheel event. To activate this, set the
`allowMouseWheel` prop to `true`.

<Example id="mouse-wheel" />

### Clamp value when user blurs the input

In most cases, users can type custom values in the input field. If the typed value is greater than the max, the value is
reset to max when the user blur out of the input.

To disable this behavior, pass `clampValueOnBlur` and set to `false`.

<Example id="no-clamp" />

### Usage within forms

To use the number input within forms, set the `name` prop.

<Example id="form-usage" />

### Format and parse value

To apply custom formatting to the input's value, set the `formatOptions` and provide `Intl.NumberFormatOptions` such as
`style` and `currency`.

<Example id="formatted" />

### Using the Field Component

The `Field` component helps manage form-related state and accessibility attributes of a number input. It includes
handling ARIA labels, helper text, and error text to ensure proper accessibility.

<Example id="with-field" />

### Using the Root Provider

The `RootProvider` component provides a context for the number-input. It accepts the value of the `useNumber-input`
hook. You can leverage it to access the component state and methods from outside the number-input.

<Example id="root-provider" />

> If you're using the `RootProvider` component, you don't need to use the `Root` component.

## Guides

### Using the Scrubber

The `NumberInput.Scrubber` component provides an interactive scrub area that allows users to drag to change the input
value. It renders as a `<div>` element and displays a custom cursor element during scrubbing interactions.

This component utilizes the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) for
smooth dragging interactions.

> **Note:** Browsers may show a notification when the Pointer Lock API is activated. The scrubber is automatically
> disabled in Safari to prevent layout shifts.

### Controlling the value

When controlling the NumberInput component, it's recommended to use string values instead of converting to numbers. This
is especially important when using `formatOptions` for currency or locale-specific formatting.

```tsx
const [value, setValue] = useState('0')

<NumberInput.Root value={value} onValueChange={(details) => setValue(details.value)}>
  {/* ... */}
</NumberInput.Root>
```

Converting values to numbers can cause issues with locale-specific formatting, particularly for currencies that use
different decimal and thousands separators (e.g., `1.523,30` vs `1,523.30`). By keeping values as strings, you preserve
the correct formatting and avoid parsing issues.

If you need to submit a numeric value in your form, use a hidden input that reads `valueAsNumber` from
`NumberInput.Context`:

```tsx
<NumberInput.Root value={value} onValueChange={(details) => setValue(details.value)}>
  <NumberInput.Input />
  <NumberInput.Context>
    {(context) => <input type="hidden" name="amount" value={context.valueAsNumber} />}
  </NumberInput.Context>
</NumberInput.Root>
```

## API Reference

### Props

<ComponentTypes id="number-input" />

### Context

These are the properties available when using `NumberInput.Context`, `useNumberInputContext` hook or `useNumberInput`
hook.

<ContextType id="number-input" />

## Accessibility

Complies with the [Spinbutton WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/).

### Keyboard Support

<KeyBindingsTable id="number-input" />
